Skip to content

StroemungsRaum: add heat equation examples using FEniCS#598

Merged
pancetta merged 23 commits intoParallel-in-Time:masterfrom
Ouardghi:pr-stroemungsraum-heat
Feb 10, 2026
Merged

StroemungsRaum: add heat equation examples using FEniCS#598
pancetta merged 23 commits intoParallel-in-Time:masterfrom
Ouardghi:pr-stroemungsraum-heat

Conversation

@Ouardghi
Copy link
Copy Markdown
Contributor

@Ouardghi Ouardghi commented Feb 5, 2026

This PR introduces the Heat Equation examples using FEniCS for the StroemungsRaum project.
The implementation is self-contained and does not affect existing projects.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Heat Equation examples using FEniCS for the StroemungsRaum research project, which focuses on parallel-in-time methods and space-time parallelization for CFD simulations. The implementation introduces problem classes, test files, accuracy analysis scripts, and plotting utilities for solving 2D heat equations with different boundary conditions using the FEniCS finite element framework.

Changes:

  • Added three problem classes for 2D heat equation solving with varying boundary condition treatments
  • Implemented test suite with problem class tests, plotting tests, and accuracy convergence tests
  • Created accuracy analysis scripts for 3rd and 5th order convergence studies
  • Added environment configuration and project README documentation

Reviewed changes

Copilot reviewed 14 out of 20 changed files in this pull request and generated 55 comments.

Show a summary per file
File Description
test_problem_class_heat_equation_FEniCS.py Basic problem class test with incorrect import path
test_plots_heat_equation_FEniCS.py Tests for visualization output generation
test_accuracy_heat_equations_FEniCS.py Convergence tests with commented-out 5th order test
run_heat_equation_FEniCS.py Main simulation runner with data export functionality
run_accuracy_3rd_order_heat_equation_FEniCS.py 3rd order convergence analysis with plotting
run_accuracy_5th_order_heat_equation_FEniCS.py 5th order convergence analysis (not tested)
HeatEquation_2D_FEniCS.py Three problem classes with comprehensive docstrings
plots_heat_equation_FEniCS.py Visualization utilities for solutions and cross-sections
environment.yml Conda environment with FEniCS dependencies
README.rst Project documentation and funding information
data/*.json, *.xdmf, *.png Generated test data and output files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2 to +4
import subprocess
import os
import warnings
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several imports are not used in this test file: subprocess, os, and warnings. These should be removed to keep the code clean.

Suggested change
import subprocess
import os
import warnings

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +4
import subprocess
import os
import warnings
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several imports are not used in this test file: subprocess, os, and warnings. These should be removed to keep the code clean.

Suggested change
import subprocess
import os
import warnings
import os

Copilot uses AI. Check for mistakes.
from mpl_toolkits.mplot3d import Axes3D


def run_simulation(ml=None, mass=None):
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unused parameter 'ml' in the function signature should be removed as it's not used in the function body and is not documented.

Suggested change
def run_simulation(ml=None, mass=None):
def run_simulation(mass=None):

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you call this function from the scripts that compute the order? Why do you have a seemingly same function thrice?


Args:
t0 (float): initial time
ml (bool): use single or multiple levels
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'ml' parameter in the docstring is mentioned but not present in the actual function signature. The docstring should be updated to remove this parameter or the parameter should be added if it's actually needed.

Suggested change
ml (bool): use single or multiple levels

Copilot uses AI. Check for mistakes.
Comment on lines +102 to +108
# mesh = df.UnitIntervalMesh(c_nvars)

mesh = df.UnitSquareMesh(c_nvars, c_nvars)

# for _ in range(refinements):
# mesh = df.refine(mesh)

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code on lines 106-107 should be removed. If mesh refinement is needed in the future, it can be retrieved from version control history.

Suggested change
# mesh = df.UnitIntervalMesh(c_nvars)
mesh = df.UnitSquareMesh(c_nvars, c_nvars)
# for _ in range(refinements):
# mesh = df.refine(mesh)
mesh = df.UnitSquareMesh(c_nvars, c_nvars)

Copilot uses AI. Check for mistakes.

import dolfin as df
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'mtri' is not used.

Suggested change
import matplotlib.tri as mtri

Copilot uses AI. Check for mistakes.
import dolfin as df
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'cm' is not used.

Suggested change
import matplotlib.cm as cm

Copilot uses AI. Check for mistakes.
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'Axes3D' is not used.

Suggested change
from mpl_toolkits.mplot3d import Axes3D

Copilot uses AI. Check for mistakes.
xdmffile_u = df.XDMFFile(path + 'heat_equation_FEniCS_Temperature.xdmf')

# load parameters
parameters = json.load(open(path + "heat_equation_FEniCS_parameters.json", 'r'))
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File is opened but is not closed.

Suggested change
parameters = json.load(open(path + "heat_equation_FEniCS_parameters.json", 'r'))
with open(path + "heat_equation_FEniCS_parameters.json", 'r') as f:
parameters = json.load(f)

Copilot uses AI. Check for mistakes.
parameters = description['problem_params']
parameters.update(description['level_params'])
parameters['Tend'] = Tend
json.dump(parameters, open(path + "heat_equation_FEniCS_parameters.json", 'w'))
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File is opened but is not closed.

Suggested change
json.dump(parameters, open(path + "heat_equation_FEniCS_parameters.json", 'w'))
with open(path + "heat_equation_FEniCS_parameters.json", 'w') as f:
json.dump(parameters, f)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@brownbaerchen brownbaerchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! The long awaited Stroemungsraum stuff is finally here!

Big PR, big number of comments. In the future, please separate your PRs into small chunks.
For instance, merge the heat equation implementation that the others derive from with a test and then do the others. This way, when you copy paste, you copy paste a version that is ready to be merged and you don't get the same comments every time.
This makes it easier for people to review your PR and improves quality of the review because the reviewers only have so much time. Also, it makes it easier for you because you can build on what you have. Getting something merged is like checking it off your todo list. It's done and doesn't get lost somewhere on your laptop.

Otherwise, please try to keep code duplication to a minimum, write more meaningful tests and only check in code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't usually check in plots to the repository. Please remove.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also don't check in output files like this. Especially because the size is quite large at 6MB. Please remove.

.. math::
u(x, y, t) = \sin(\pi x)\sin(\pi y)\cos(t) + c.

In this class the problem is implemented in the way that the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this class the problem is implemented in the way that the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem
In this class the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem

C. Richardson, J. Ring, M. E. Rognes, G. N. Wells. Archive of Numerical Software (2015).
.. [2] Automated Solution of Differential Equations by the Finite Element Method. A. Logg, K.-A. Mardal, G. N.
Wells and others. Springer (2012).
"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I see the docstring was originally copy-pasted, is it still up to date?

dtype_f = rhs_fenics_mesh

def __init__(self, c_nvars=64, t0=0.0, family='CG', order=2, refinements=1, nu=0.1, c=0.0):
"""Initialization routine"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Initialization routine"""

@pytest.mark.fenics
@pytest.mark.mpi4py
@pytest.mark.parametrize('mass', [True])
def test_plot(mass):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have decided not to test plotting. Please add # pragma: no cover to tell coverage to exclude your plotting function from the report. In particular, you do:

def plot_stuff():  # pragma: no cover
   ...

BUT: only exclude pure plotting functions! Do not exclude functions that do analysis or run a simulation. That is our current convention of coverage rules.

assert os.path.isfile('data/heat_equation_FEniCS_Temperature.xdmf'), 'ERROR: Temperature.xdmf does not exist'
assert os.path.isfile('data/heat_equation_FEniCS_Temperature.h5'), 'ERROR: Temperature.h5 does not exist'

from pySDC.projects.StroemungsRaum.plotting.plots_heat_equation_FEniCS import plot_solutions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also remove / change this test.

def test_problem_class(mass):
from pySDC.projects.FluidFlow.run_heat_equation_FEniCS import run_simulation

run_simulation(mass=mass)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, please don't just do a smoke test. You know the exact solution, so here you can even just compare the two.

What I like to do is define an input where I know the output and call the right hand side evaluation and solve functions on that. For instance, the second derivative of a sine wave is again a sine wave. Maybe this is difficult with the way dirichlet boundary conditions are handled in FEM, I don't know. But please try to come up with some simple tests.

-------
Funded by the **German Federal Ministry of Education and Research (BMBF)** under
grant number **16ME0708**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you want to add how to reproduce the results in your paper here?

from mpl_toolkits.mplot3d import Axes3D


def run_simulation(ml=None, mass=None):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you call this function from the scripts that compute the order? Why do you have a seemingly same function thrice?

@Ouardghi
Copy link
Copy Markdown
Contributor Author

Ouardghi commented Feb 9, 2026

The review comments have been addressed by splitting the code and keeping only the heat equation implementation in this PR. A simple but more meaningful test was added, where the relative error is checked instead of only verifying file creation or execution. This should make the PR easier to review and provide a cleaner base for adding the other examples in follow-up PRs.

Copy link
Copy Markdown
Contributor

@brownbaerchen brownbaerchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot! Much easier to review!

It's a lot of comments, but most of it is tiny things that you can just commit right here.

Comment thread pySDC/projects/StroemungsRaum/problem_classes/HeatEquation_2D_FEniCS.py Outdated
Comment on lines +90 to +91
logging.getLogger('FFC').setLevel(logging.WARNING)
logging.getLogger('UFL').setLevel(logging.WARNING)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed? Do they log a lot on info level? Or too much on debug level?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mainly used during debugging to reduce verbose output from FFC and UFL. It is not essential and can be removed if preferred.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I leave it up to you

Comment thread pySDC/projects/StroemungsRaum/tests/test_heat_equation_FEniCS.py
Comment thread pySDC/projects/StroemungsRaum/tests/test_heat_equation_FEniCS.py Outdated
Comment thread pySDC/projects/StroemungsRaum/tests/test_heat_equation_FEniCS.py Outdated
Comment thread pySDC/projects/StroemungsRaum/run_heat_equation_FEniCS.py Outdated
Comment thread pySDC/projects/StroemungsRaum/run_heat_equation_FEniCS.py Outdated
Comment thread pySDC/projects/StroemungsRaum/run_heat_equation_FEniCS.py Outdated
Comment thread pySDC/projects/StroemungsRaum/run_heat_equation_FEniCS.py Outdated

return P, stats, rel_err

def run_postprocessing(description, problem, stats, Tend):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not tested, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not tested, as it only performs postprocessing by writing files and does not contain computational logic.

Ouardghi and others added 17 commits February 9, 2026 13:34
…FEniCS.py

Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Co-authored-by: Thomas Saupe <39156931+brownbaerchen@users.noreply.github.com>
Removed logging level settings for FFC and UFL.
Copy link
Copy Markdown
Contributor

@brownbaerchen brownbaerchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot! If the tests pass, we can merge like this.

@brownbaerchen
Copy link
Copy Markdown
Contributor

What's wrong with the tests why are they stuck in the queue? Did copilot trigger too many tests @pancetta?

@pancetta
Copy link
Copy Markdown
Member

pancetta commented Feb 9, 2026

@brownbaerchen
Copy link
Copy Markdown
Contributor

No, but @Ouardghi did, see https://github.com/Parallel-in-Time/pySDC/actions

Not sure that this is true. This PR was tested at 11:30, but none of the workflows triggered by later pushes ran. If Abdel had overwhelmed the CI, wouldn't the first action in the series of commits have run?

@brownbaerchen
Copy link
Copy Markdown
Contributor

Never mind! The workflows are working and flowing again!

@pancetta
Copy link
Copy Markdown
Member

Please fix linting. I'm not sure I understand what the matter is with the fenics tests, though

@pancetta
Copy link
Copy Markdown
Member

Copilot suggests to add setuptools explicitly to the etc/environment-fenics.yml, but there is no explanation why this popped up now.

@brownbaerchen
Copy link
Copy Markdown
Contributor

It now fails on master as well, see here.

@pancetta
Copy link
Copy Markdown
Member

See PR #616

@pancetta pancetta merged commit a1e6338 into Parallel-in-Time:master Feb 10, 2026
79 of 80 checks passed
@Ouardghi Ouardghi deleted the pr-stroemungsraum-heat branch February 10, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants